/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2021 Ramaxel Memory Technology, Ltd */

#ifndef SPHW_MT_H
#define SPHW_MT_H

#define NICTOOL_CMD_TYPE 0x18

struct api_cmd_rd {
	u32 pf_id;
	u8 dest;
	u8 *cmd;
	u16 size;
	void *ack;
	u16 ack_size;
};

struct api_cmd_wr {
	u32 pf_id;
	u8 dest;
	u8 *cmd;
	u16 size;
};

struct pf_dev_info {
	u64 bar0_size;
	u8 bus;
	u8 slot;
	u8 func;
	u64 phy_addr;
};

/* Indicates the maximum number of interrupts that can be recorded.
 * Subsequent interrupts are not recorded in FFM.
 */
#define FFM_RECORD_NUM_MAX 64

struct ffm_intr_info {
	u8 node_id;
	/* error level of the interrupt source */
	u8 err_level;
	/* Classification by interrupt source properties */
	u16 err_type;
	u32 err_csr_addr;
	u32 err_csr_value;
};

struct ffm_intr_tm_info {
	struct ffm_intr_info intr_info;
	u8 times;
	u8 sec;
	u8 min;
	u8 hour;
	u8 mday;
	u8 mon;
	u16 year;
};

struct ffm_record_info {
	u32 ffm_num;
	u32 last_err_csr_addr;
	u32 last_err_csr_value;
	struct ffm_intr_tm_info ffm[FFM_RECORD_NUM_MAX];
};

struct dbgtool_k_glb_info {
	struct semaphore dbgtool_sem;
	struct ffm_record_info *ffm;
};

struct msg_2_up {
	u8 pf_id;
	u8 mod;
	u8 cmd;
	void *buf_in;
	u16 in_size;
	void *buf_out;
	u16 *out_size;
};

struct dbgtool_param {
	union {
		struct api_cmd_rd api_rd;
		struct api_cmd_wr api_wr;
		struct pf_dev_info *dev_info;
		struct ffm_record_info *ffm_rd;
		struct msg_2_up msg2up;
	} param;
	char chip_name[16];
};

/* dbgtool command type */
/* You can add commands as required. The dbgtool command can be
 * used to invoke all interfaces of the kernel-mode x86 driver.
 */
enum dbgtool_cmd {
	DBGTOOL_CMD_API_RD = 0,
	DBGTOOL_CMD_API_WR,
	DBGTOOL_CMD_FFM_RD,
	DBGTOOL_CMD_FFM_CLR,
	DBGTOOL_CMD_PF_DEV_INFO_GET,
	DBGTOOL_CMD_MSG_2_UP,
	DBGTOOL_CMD_FREE_MEM,
	DBGTOOL_CMD_NUM
};

#define PF_MAX_SIZE 16
#define BUSINFO_LEN 32
#define SELF_TEST_BAR_ADDR_OFFSET 0x883c

enum module_name {
	SEND_TO_NPU = 1,
	SEND_TO_MPU,
	SEND_TO_SM,

	SEND_TO_HW_DRIVER,
	SEND_TO_NIC_DRIVER,
	SEND_TO_OVS_DRIVER,
	SEND_TO_ROCE_DRIVER,
	SEND_TO_TOE_DRIVER,
	SEND_TO_IWAP_DRIVER,
	SEND_TO_FC_DRIVER,
	SEND_FCOE_DRIVER,
};

enum driver_cmd_type {
	TX_INFO = 1,
	Q_NUM,
	TX_WQE_INFO,
	TX_MAPPING,
	RX_INFO,
	RX_WQE_INFO,
	RX_CQE_INFO,
	UPRINT_FUNC_EN,
	UPRINT_FUNC_RESET,
	UPRINT_SET_PATH,
	UPRINT_GET_STATISTICS,
	FUNC_TYPE,
	GET_FUNC_IDX,
	GET_INTER_NUM,
	CLOSE_TX_STREAM,
	GET_DRV_VERSION,
	CLEAR_FUNC_STASTIC,
	GET_HW_STATS,
	CLEAR_HW_STATS,
	GET_SELF_TEST_RES,
	GET_CHIP_FAULT_STATS,
	NIC_RSVD1,
	NIC_RSVD2,
	NIC_RSVD3,
	GET_CHIP_ID,
	GET_SINGLE_CARD_INFO,
	GET_FIRMWARE_ACTIVE_STATUS,
	ROCE_DFX_FUNC,
	GET_DEVICE_ID,
	GET_PF_DEV_INFO,
	CMD_FREE_MEM,
	GET_LOOPBACK_MODE = 32,
	SET_LOOPBACK_MODE,
	SET_LINK_MODE,
	SET_PF_BW_LIMIT,
	GET_PF_BW_LIMIT,
	ROCE_CMD,
	GET_POLL_WEIGHT,
	SET_POLL_WEIGHT,
	GET_HOMOLOGUE,
	SET_HOMOLOGUE,
	GET_SSET_COUNT,
	GET_SSET_ITEMS,
	IS_DRV_IN_VM,
	LRO_ADPT_MGMT,
	SET_INTER_COAL_PARAM,
	GET_INTER_COAL_PARAM,
	GET_CHIP_INFO,
	GET_NIC_STATS_LEN,
	GET_NIC_STATS_STRING,
	GET_NIC_STATS_INFO,
	GET_PF_ID,
	NIC_RSVD4,
	NIC_RSVD5,
	DCB_QOS_INFO,
	DCB_PFC_STATE,
	DCB_ETS_STATE,
	DCB_STATE,
	NIC_RSVD6,
	NIC_RSVD7,
	GET_ULD_DEV_NAME,

	RSS_CFG = 0x40,
	RSS_INDIR,
	PORT_ID,

	GET_FUNC_CAP = 0x50,

	GET_WIN_STAT = 0x60,
	WIN_CSR_READ = 0x61,
	WIN_CSR_WRITE = 0x62,
	WIN_API_CMD_RD = 0x63,

	VM_COMPAT_TEST = 0xFF
};

enum api_chain_cmd_type {
	API_CSR_READ,
	API_CSR_WRITE
};

enum sm_cmd_type {
	SM_CTR_RD32 = 1,
	SM_CTR_RD64_PAIR,
	SM_CTR_RD64,
	SM_CTR_RD32_CLEAR,
	SM_CTR_RD64_PAIR_CLEAR,
	SM_CTR_RD64_CLEAR
};

struct cqm_stats {
	atomic_t cqm_cmd_alloc_cnt;
	atomic_t cqm_cmd_free_cnt;
	atomic_t cqm_send_cmd_box_cnt;
	atomic_t cqm_send_cmd_imm_cnt;
	atomic_t cqm_db_addr_alloc_cnt;
	atomic_t cqm_db_addr_free_cnt;
	atomic_t cqm_fc_srq_create_cnt;
	atomic_t cqm_srq_create_cnt;
	atomic_t cqm_rq_create_cnt;
	atomic_t cqm_qpc_mpt_create_cnt;
	atomic_t cqm_nonrdma_queue_create_cnt;
	atomic_t cqm_rdma_queue_create_cnt;
	atomic_t cqm_rdma_table_create_cnt;
	atomic_t cqm_qpc_mpt_delete_cnt;
	atomic_t cqm_nonrdma_queue_delete_cnt;
	atomic_t cqm_rdma_queue_delete_cnt;
	atomic_t cqm_rdma_table_delete_cnt;
	atomic_t cqm_func_timer_clear_cnt;
	atomic_t cqm_func_hash_buf_clear_cnt;
	atomic_t cqm_scq_callback_cnt;
	atomic_t cqm_ecq_callback_cnt;
	atomic_t cqm_nocq_callback_cnt;
	atomic_t cqm_aeq_callback_cnt[112];
};

enum sphw_fault_err_level {
	FAULT_LEVEL_FATAL,
	FAULT_LEVEL_SERIOUS_RESET,
	FAULT_LEVEL_HOST,
	FAULT_LEVEL_SERIOUS_FLR,
	FAULT_LEVEL_GENERAL,
	FAULT_LEVEL_SUGGESTION,
	FAULT_LEVEL_MAX,
};

struct link_event_stats {
	atomic_t link_down_stats;
	atomic_t link_up_stats;
};

enum sphw_fault_type {
	FAULT_TYPE_CHIP,
	FAULT_TYPE_UCODE,
	FAULT_TYPE_MEM_RD_TIMEOUT,
	FAULT_TYPE_MEM_WR_TIMEOUT,
	FAULT_TYPE_REG_RD_TIMEOUT,
	FAULT_TYPE_REG_WR_TIMEOUT,
	FAULT_TYPE_PHY_FAULT,
	FAULT_TYPE_MAX,
};

struct fault_event_stats {
	atomic_t chip_fault_stats[22][FAULT_LEVEL_MAX];
	atomic_t fault_type_stat[FAULT_TYPE_MAX];
	atomic_t pcie_fault_stats;
};

struct sphw_hw_stats {
	atomic_t heart_lost_stats;
	struct cqm_stats cqm_stats;
	struct link_event_stats link_event_stats;
	struct fault_event_stats fault_event_stats;
};

#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif

struct pf_info {
	char name[IFNAMSIZ];
	char bus_info[BUSINFO_LEN];
	u32 pf_type;
};

struct card_info {
	struct pf_info pf[PF_MAX_SIZE];
	u32 pf_num;
};

struct spnic_nic_loop_mode {
	u32 loop_mode;
	u32 loop_ctrl;
};

enum spnic_show_set {
	SHOW_SSET_IO_STATS = 1,
};

#define SPNIC_SHOW_ITEM_LEN 32
struct spnic_show_item {
	char name[SPNIC_SHOW_ITEM_LEN];
	u8 hexadecimal; /* 0: decimal , 1: Hexadecimal */
	u8 rsvd[7];
	u64 value;
};

#define SPHW_CHIP_FAULT_SIZE (110 * 1024)
#define MAX_DRV_BUF_SIZE 4096

struct nic_cmd_chip_fault_stats {
	u32 offset;
	u8 chip_fault_stats[MAX_DRV_BUF_SIZE];
};

#define NIC_TOOL_MAGIC 'x'

#define CARD_MAX_SIZE	16
struct nic_card_id {
	u32 id[CARD_MAX_SIZE];
	u32 num;
};

struct func_pdev_info {
	u64 bar0_phy_addr;
	u64 bar0_size;
	u64 bar1_phy_addr;
	u64 bar1_size;
	u64 bar3_phy_addr;
	u64 bar3_size;
	u64 rsvd1[4];
};

struct sphw_card_func_info {
	u32 num_pf;
	u32 rsvd0;
	u64 usr_api_phy_addr;
	struct func_pdev_info pdev_info[CARD_MAX_SIZE];
};

struct wqe_info {
	int q_id;
	void *slq_handle;
	unsigned int wqe_id;
};

#define MAX_VER_INFO_LEN 128
struct drv_version_info {
	char ver[MAX_VER_INFO_LEN];
};

struct spnic_tx_hw_page {
	u64 phy_addr;
	u64 *map_addr;
};

struct nic_sq_info {
	u16 q_id;
	u16 pi;
	u16 ci; /* sw_ci */
	u16 fi; /* hw_ci */
	u32 q_depth;
	u16 pi_reverse;
	u16 wqebb_size;
	u8 priority;
	u16 *ci_addr;
	u64 cla_addr;
	void *slq_handle;
	struct spnic_tx_hw_page direct_wqe;
	struct spnic_tx_hw_page doorbell;
	u32 page_idx;
	u32 glb_sq_id;
};

struct nic_rq_info {
	u16 q_id;
	u16 glb_rq_id;
	u16 hw_pi;
	u16 ci; /* sw_ci */
	u16 sw_pi;
	u16 wqebb_size;
	u16 q_depth;
	u16 buf_len;

	void *slq_handle;
	u64 ci_wqe_page_addr;
	u64 ci_cla_tbl_addr;

	u8 coalesc_timer_cfg;
	u8 pending_limt;
	u16 msix_idx;
	u32 msix_vector;
};

#define MT_EPERM        1       /* Operation not permitted */
#define MT_EIO          2       /* I/O error */
#define MT_EINVAL       3       /* Invalid argument */
#define	MT_EBUSY        4       /* Device or resource busy */
#define MT_EOPNOTSUPP   0xFF    /* Operation not supported */

struct mt_msg_head {
	u8 status;
	u8 rsvd1[3];
};

#define MT_DCB_OPCODE_WR   BIT(0)  /* 1 - write, 0 - read */
struct spnic_mt_qos_info {
	struct mt_msg_head head;

	u16 op_code;
	u8 valid_cos_bitmap;
	u8 valid_up_bitmap;
	u32 rsvd1;
};

struct spnic_mt_dcb_state {
	struct mt_msg_head head;

	u16 op_code;
	u8 state;
	u8 rsvd;
};

#define MT_DCB_ETS_UP_TC      BIT(1)
#define MT_DCB_ETS_UP_BW      BIT(2)
#define MT_DCB_ETS_UP_PRIO    BIT(3)
#define MT_DCB_ETS_TC_BW      BIT(4)
#define MT_DCB_ETS_TC_PRIO    BIT(5)

#define DCB_UP_TC_NUM         0x8
struct spnic_mt_ets_state {
	struct mt_msg_head head;

	u16 op_code;
	u8 up_tc[DCB_UP_TC_NUM];
	u8 up_bw[DCB_UP_TC_NUM];
	u8 tc_bw[DCB_UP_TC_NUM];
	u8 up_prio_bitmap;
	u8 tc_prio_bitmap;
	u32 rsvd;
};

#define MT_DCB_PFC_PFC_STATE  BIT(1)
#define MT_DCB_PFC_PFC_PRI_EN BIT(2)
struct spnic_mt_pfc_state {
	struct mt_msg_head head;

	u16 op_code;
	u8 state;
	u8 pfc_en_bitpamp;
	u32 rsvd;
};

enum mt_api_type {
	API_TYPE_MBOX = 1,
	API_TYPE_API_CHAIN_BYPASS,
	API_TYPE_API_CHAIN_TO_MPU,
	API_TYPE_CLP,
};

struct npu_cmd_st {
	u32 mod : 8;
	u32 cmd : 8;
	u32 ack_type : 3;
	u32 direct_resp : 1;
	u32 len : 12;
};

struct mpu_cmd_st {
	u32 api_type : 8;
	u32 mod : 8;
	u32 cmd : 16;
};

struct msg_module {
	char device_name[IFNAMSIZ];
	u32 module;
	union {
		u32 msg_formate; /* for driver */
		struct npu_cmd_st npu_cmd;
		struct mpu_cmd_st mpu_cmd;
	};
	u32 timeout; /* for mpu/npu cmd */
	u32 func_idx;
	u32 buf_in_size;
	u32 buf_out_size;
	void *in_buf;
	void *out_buf;
	int bus_num;
	u32 rsvd2[5];
};

int alloc_buff_in(void *hwdev, struct msg_module *nt_msg, u32 in_size, void **buf_in);

int alloc_buff_out(void *hwdev, struct msg_module *nt_msg, u32 out_size, void **buf_out);

void free_buff_in(void *hwdev, struct msg_module *nt_msg, void *buf_in);

void free_buff_out(void *hwdev, struct msg_module *nt_msg, void *buf_out);

int copy_buf_out_to_user(struct msg_module *nt_msg, u32 out_size, void *buf_out);

int get_func_type(void *hwdev, const void *buf_in, u32 in_size, void *buf_out, u32 *out_size);

int get_func_id(void *hwdev, const void *buf_in, u32 in_size, void *buf_out, u32 *out_size);

int get_drv_version(void *hwdev, const void *buf_in, u32 in_size, void *buf_out, u32 *out_size);

int get_hw_driver_stats(const void *hwdev, const void *buf_in, u32 in_size, void *buf_out,
			u32 *out_size);

int clear_hw_driver_stats(void *hwdev, const void *buf_in, u32 in_size, void *buf_out,
			  u32 *out_size);

int get_chip_faults_stats(const void *hwdev, const void *buf_in, u32 in_size, void *buf_out,
			  u32 *out_size);

int get_chip_id_test(void *hwdev, const void *buf_in, u32 in_size, void *buf_out, u32 *out_size);

int send_to_mpu(void *hwdev, struct msg_module *nt_msg, void *buf_in, u32 in_size, void *buf_out,
		u32 *out_size);
int send_to_npu(void *hwdev, struct msg_module *nt_msg, void *buf_in, u32 in_size, void *buf_out,
		u32 *out_size);

int send_to_sm(void *hwdev, struct msg_module *nt_msg, void *buf_in, u32 in_size, void *buf_out,
	       u32 *out_size);

#endif /* SPHW_MT_H_ */
